﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Collections.Specialized;
using System.Web;
using System.ComponentModel;

namespace Enter.Common
{
    /// <summary>
    /// 集合
    /// </summary>
    public class RequestHelper : NameObjectCollectionBase, ICloneable
    {
        public enum EnumUrl : byte
        { /// <summary>
            /// 替换
            /// </summary>
            [Description("替换")]
            Replace = 0,
            /// <summary>
            /// 附加
            /// </summary>
            [Description("附加")]
            append = 1

        }

        /// <summary>
        /// 
        /// </summary>
        protected  NameValueCollection _list;
        private string _encode;

        #region 构造函数
        /// <summary>
        /// 构造函数
        /// </summary>
        public RequestHelper()
        {
            _list = new NameValueCollection();
            _encode = "GB2312";
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="encode"></param>
        public RequestHelper(string encode)
        {
            _list = new NameValueCollection();
            _encode = encode;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="col"></param>
        public RequestHelper(NameValueCollection col)
        {
            _list = new NameValueCollection(col);
            _encode = "GB2312";
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="col"></param>
        /// <param name="encode"></param>
        public RequestHelper(NameValueCollection col, string encode)
        {
            _list = new NameValueCollection(col);
            _encode = encode;
        }
        #endregion

        /// <summary>
        /// 包含在 System.Collections.Specialized.NameObjectCollectionBase 实例中的键/值对的数目。
        /// </summary>
        public override int Count
        {
            get { return _list.Count; }
        }
        #region 常用属性
        /// <summary>
        /// 将具有指定名称和值的项添加到 System.Collections.Specialized.NameValueCollection。
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        public void Add(string name, string value)
        {
            _list.Add(name, value);
        }
        /// <summary>
        /// 将具有指定名称和值的项添加到 System.Collections.Specialized.NameValueCollection。
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        public void Add(string name, int value)
        {
            _list.Add(name, value.ToString());
        }
        /// <summary>
        /// 将具有指定名称和值的项添加到 System.Collections.Specialized.NameValueCollection。
        /// </summary>
        /// <param name="name"></param>
        /// <param name="obj"></param>
        public void Add(string name, object obj)
        {
            _list.Add(name, obj.ToString());
        }
        /// <summary>
        /// 移除 System.Collections.Specialized.NameObjectCollectionBase 实例中具有指定键的项。
        /// </summary>
        /// <param name="name"></param>
        public void Remove(string name)
        {
            _list.Remove(name);
        }
        /// <summary>
        /// 从一个NameValueCollection复制值
        /// </summary>
        /// <param name="list"></param>
        /// <param name="name"></param>
        public void Copy(RequestHelper list, string name)
        {
            _list.Set(name, list[name]);
        }
        public new string[] Keys
        {
            get { return _list.AllKeys; }
        }

        /// <summary>
        /// 设置 System.Collections.Specialized.NameValueCollection 中某个项的值。
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        public  void Set(string name, string value)
        {
            _list.Set(name, value);
        }
        public void Set(string name, string format, params object[] args)
        {
            _list.Set(name, string.Format(format, args));
        }
        /// <summary>
        /// 设置 System.Collections.Specialized.NameValueCollection 中某个项的值。
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        public void Set(string name, string value, EnumUrl mode)
        {
           
            string old = GetString(name);
            if (string.IsNullOrEmpty(old))
            {
                Set(name, value);
            }
            else
            {
                if (mode == EnumUrl.Replace)
                { Set(name, value); }
                else if (mode == EnumUrl.append)
                {
                    if (!old.Contains(value))
                    {
                        Set(name, old + ";" + value);
                    }
                }
            }
        }
        /// <summary>
        /// 设置 System.Collections.Specialized.NameValueCollection 中某个项的值。
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        public string SetAndGetString(string name, string value, EnumUrl mode)
        {
            Set(name, value, mode);
            return ToQueryString();
        }
        /// <summary>
        /// 设置 System.Collections.Specialized.NameValueCollection 中某个项的值。
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        public string SetAndGetString(string name, string value)
        {
            Set(name, value);
            return ToQueryString();
        }
        /// <summary>
        /// 从参数NameValueCollection复制多个值
        /// </summary>
        /// <param name="list"></param>
        /// <param name="names"></param>
        public void Copy(RequestHelper list, params string[] names)
        {
            foreach (string key in names)
            {
                _list.Set(key, list[key]);
            }
        }
        /// <summary>
        /// 使缓存数组无效，并将所有项从 System.Collections.Specialized.NameValueCollection 中移除。
        /// </summary>
        public void Clear()
        {
            _list.Clear();
        }
        /// <summary>
        ///  获取 System.Collections.Specialized.NameValueCollection 中指定索引处的项。
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public string this[int index]
        {
            get { return _list[index]; }
        }
        /// <summary>
        /// 获取或设置 System.Collections.Specialized.NameValueCollection 中具有指定键的项。
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public string this[string name]
        {
            get { return _list[name] ?? ""; }
            set { _list[name] = value; }
        }
        #endregion

        #region 获取类型
        /// <summary>
        /// 返回字符串类型
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public  string GetString(string name)
        {
            return _list[name];
        }
        /// <summary>
        /// 返回字符串类型
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public string GetString(string name, Encoding e)
        {
            return HttpUtility.UrlDecode(_list[name], e);
        }
        /// <summary>
        /// 返回整数类型
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public int GetInt(string name)
        {
            return Convert.ToInt32(_list[name]);
        }
        /// <summary>
        /// 返回BYTE类型的
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public byte GetByte(string name)
        {
            try
            {
                return Convert.ToByte(_list[name]);
            }
            catch { return 0; }
        }
        /// <summary>
        /// 返回Decimal类型
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public decimal GetDecimal(string name)
        {
            return Convert.ToDecimal(_list[name]);
        }
        /// <summary>
        /// 返回DateTime类型
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public DateTime GetDateTime(string name)
        {
            return Convert.ToDateTime(_list[name]);
        }
        #endregion

        #region 迭代器方法
        /// <summary>
        /// 迭代器方法
        /// </summary>
        /// <returns></returns>
        public System.Collections.IEnumerator GetEnumerator()
        {
            for (int i = 0; i < _list.Count; i++)
            {
                yield return _list[i];
            }
        }
        #endregion

        /// <summary>
        /// 转换成URL参数
        /// </summary>
        /// <returns></returns>
        public string ToQueryString()
        {
            if (_list.Count == 0)
                return "";
            string[] queryStringArray = new string[_list.Count];
            for (int i = 0; i < _list.Count; i++)
            {
                string key = _list.Keys[i];
                queryStringArray[i] = string.Format("{0}={1}", HttpUtility.UrlEncode(key, Encoding.GetEncoding(_encode)), HttpUtility.UrlEncode(_list[key], Encoding.GetEncoding(_encode)));
            }
            string result = string.Join("&", queryStringArray);
            return result;
        }
        /// <summary>
        /// 转换成字符串 不编码
        /// </summary>
        /// <returns></returns>
        public string ToDbQueryString()
        {
            if (_list.Count == 0)
                return "";
            string[] queryStringArray = new string[_list.Count];
            for (int i = 0; i < _list.Count; i++)
            {
                string key = _list.Keys[i];
                queryStringArray[i] = string.Format("{0}={1}", key, _list[key]);
            }
            string result = string.Join("&", queryStringArray);
            return result;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="encodeList"></param>
        /// <returns></returns>
        public string ToEnQueryString(string encodeList)
        {
            if (_list.Count == 0)
                return "";
            string[] queryStringArray = new string[_list.Count];
            encodeList = "," + encodeList.ToLower() + ",";
            for (int i = 0; i < _list.Count; i++)
            {
                string key = _list.Keys[i];

                if (encodeList.IndexOf("," + key.ToLower() + ",") != -1)
                {
                    queryStringArray[i] = string.Format("{0}={1}", key, HttpUtility.UrlEncode(_list[key]));
                }
                else
                {
                    queryStringArray[i] = string.Format("{0}={1}", key, _list[key]);
                }
            }
            string result = string.Join("&", queryStringArray);
            return result;
        }
        /// <summary>
        /// 把字符串
        /// </summary>
        /// <param name="querystring"></param>
        /// <returns></returns>
        public bool ToQueryParam(string querystring)
        {
            if (string.IsNullOrEmpty(querystring))
            {
                return false;
            }
            try
            {
                string[] queryparams = querystring.Split('&');
                foreach (string queryparam in queryparams)
                {
                    string[] pars = queryparam.Split('=');
                    string name = pars[0];
                    string value = pars.Length == 2 ? pars[1] : "";
                    _list.Add(name, System.Web.HttpUtility.UrlDecode(value, Encoding.GetEncoding(_encode)));
                }
                return true;
            }
            catch
            {
                return false;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="querystring"></param>
        /// <param name="encode"></param>
        /// <returns></returns>
        public static RequestHelper ToQueryParamWithEncode(string querystring, Encoding encode)
        {
            if (string.IsNullOrEmpty(querystring))
            {
                return new RequestHelper();
            }
            try
            {
                RequestHelper list = new RequestHelper();
                string[] queryparams = querystring.Split('&');
                foreach (string queryparam in queryparams)
                {
                    string[] pars = queryparam.Split('=');
                    string name = pars[0];
                    string value = pars.Length == 2 ? pars[1] : "";
                    list.Add(name, System.Web.HttpUtility.UrlDecode(value, encode));
                }
                return list;
            }
            catch
            {
                throw new Exception("参数错误");
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="querystring"></param>
        /// <returns></returns>
        public static RequestHelper ToQueryParamFunc(string querystring)
        {
            if (string.IsNullOrEmpty(querystring))
            {
                return new RequestHelper();
            }
            try
            {
                RequestHelper list = new RequestHelper();
                string[] queryparams = querystring.Split('&');
                foreach (string queryparam in queryparams)
                {
                    string[] pars = queryparam.Split('=');
                    string name = pars[0];
                    string value = pars.Length == 2 ? pars[1] : "";
                    list.Add(name, value);
                }
                return list;
            }
            catch
            {
                throw new Exception("参数错误");
            }
        }
        /// <summary>
        /// 直接通过HTTP方式提交到远程服务器
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public RequestHelper SendByPost(string url)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "POST";
            request.Timeout = 120000;
            request.ContentType = "application/x-www-form-urlencoded";
            byte[] buffer = Encoding.GetEncoding("GB2312").GetBytes(this.ToQueryString());
            request.ContentLength = buffer.Length;
            Stream requestStream = request.GetRequestStream();
            requestStream.Write(buffer, 0, buffer.Length);
            requestStream.Close();

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("GB2312"));
            string result = sr.ReadToEnd();
            sr.Close();
            response.Close();

            RequestHelper responseCollection = new RequestHelper();
            if (responseCollection.ToQueryParam(result))
                return responseCollection;
            else
                return null;
        }


        #region ICloneable 成员

        public object Clone()
        {
            RequestHelper request = new RequestHelper();
            foreach (string key in this.Keys)
            {
                request.Add(key, this[key]);
            }
            return request;
        }

        #endregion
    }
}
